/*-------------------------------------------------------------------------
 *
 * execdebug.h
 *	  支配执行器调试行为的 #defines
 *
 * XXX 这一切都很旧且笨拙。较新的代码往往使用 elog() 
 * 进行调试打印，因为这比 printf() 更灵活。
 *
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/executor/execdebug.h
 *
 *-------------------------------------------------------------------------
 */
#ifndef EXECDEBUG_H
#define EXECDEBUG_H

#include "executor/executor.h"
#include "nodes/print.h"

/* ----------------------------------------------------------------
 *		调试定义。
 *
 *		如果您想要某些调试行为，请将该变量 #define 为 1。
 *		不需要显式 #undef，因为我们可以使用 -D 编译器选项启用功能。
 *		- thomas 1999-02-20
 * ----------------------------------------------------------------
 */

/* ----------------
 *		EXEC_NESTLOOPDEBUG 是一个标志，用于通过 NL_printf() 和
 *		ENL_printf() 在 nodeNestloop.c 中开启嵌套循环节点的调试
 * ----------------
#undef EXEC_NESTLOOPDEBUG
 */

/* ----------------
 *		EXEC_SORTDEBUG 是一个标志，用于通过 SO_printf() 在
 *		nodeSort.c 中开启 ExecSort() 的调试
 * ----------------
#undef EXEC_SORTDEBUG
 */

/* ----------------
 *		EXEC_MERGEJOINDEBUG 是一个标志，用于通过 MJ_printf() 在
 *		nodeMergejoin.c 中开启 ExecMergeJoin() 的调试
 * ----------------
#undef EXEC_MERGEJOINDEBUG
 */

/* ----------------------------------------------------------------
 *		以上定义控制的 #defines
 *
 *		注意：这些大多数是 "不完整" 的，因为我不需要未定义的那部分。
 *			  仅在必要时添加更多 -cim 10/26/89
 * ----------------------------------------------------------------
 */
#define T_OR_F(b)				((b) ? "true" : "false")
#define NULL_OR_TUPLE(slot)		(TupIsNull(slot) ? "null" : "a tuple")

/* ----------------
 *		嵌套循环调试定义
 * ----------------
 */
#ifdef EXEC_NESTLOOPDEBUG
#define NL_nodeDisplay(l)				nodeDisplay(l)
#define NL_printf(s)					printf(s)
#define NL1_printf(s, a)				printf(s, a)
#define ENL1_printf(message)			printf("ExecNestLoop: %s\n", message)
#else
#define NL_nodeDisplay(l)
#define NL_printf(s)
#define NL1_printf(s, a)
#define ENL1_printf(message)
#endif							/* EXEC_NESTLOOPDEBUG */

/* ----------------
 *		排序节点调试定义
 * ----------------
 */
#ifdef EXEC_SORTDEBUG
#define SO_nodeDisplay(l)				nodeDisplay(l)
#define SO_printf(s)					printf(s)
#define SO1_printf(s, p)				printf(s, p)
#define SO2_printf(s, p1, p2)			printf(s, p1, p2)
#else
#define SO_nodeDisplay(l)
#define SO_printf(s)
#define SO1_printf(s, p)
#define SO2_printf(s, p1, p2)
#endif							/* EXEC_SORTDEBUG */

/* ----------------
 *		合并连接调试定义
 * ----------------
 */
#ifdef EXEC_MERGEJOINDEBUG

#define MJ_nodeDisplay(l)				nodeDisplay(l)
#define MJ_printf(s)					printf(s)
#define MJ1_printf(s, p)				printf(s, p)
#define MJ2_printf(s, p1, p2)			printf(s, p1, p2)
#define MJ_debugtup(slot)				debugtup(slot, NULL)
#define MJ_dump(state)					ExecMergeTupleDump(state)
#define MJ_DEBUG_COMPARE(res) \
  MJ1_printf("  MJCompare() returns %d\n", (res))
#define MJ_DEBUG_QUAL(clause, res) \
  MJ2_printf("  ExecQual(%s, econtext) returns %s\n", \
			 CppAsString(clause), T_OR_F(res))
#define MJ_DEBUG_PROC_NODE(slot) \
  MJ2_printf("  %s = ExecProcNode(...) returns %s\n", \
			 CppAsString(slot), NULL_OR_TUPLE(slot))
#else

#define MJ_nodeDisplay(l)
#define MJ_printf(s)
#define MJ1_printf(s, p)
#define MJ2_printf(s, p1, p2)
#define MJ_debugtup(slot)
#define MJ_dump(state)
#define MJ_DEBUG_COMPARE(res)
#define MJ_DEBUG_QUAL(clause, res)
#define MJ_DEBUG_PROC_NODE(slot)
#endif							/* EXEC_MERGEJOINDEBUG */

#endif							/* EXECDEBUG_H */
